package edu.hrbu.trade01.aspect;

import edu.hrbu.trade01.annotation.MyLog;
import edu.hrbu.trade01.entity.OperLog;
import edu.hrbu.trade01.entity.User;
import edu.hrbu.trade01.service.OperLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Objects;

import static edu.hrbu.trade01.util.ConstUtil.LOG_ERROR;
import static edu.hrbu.trade01.util.ConstUtil.LOG_SUCCESS;

/**
 * @author 徐登宇
 */
@Order(1)
@Slf4j
@Aspect
@Component
public class LogAspect {

    @Autowired
    private OperLogService operLogService;

    // 返回通知
    @AfterReturning("@annotation(mylog)")
    public void afterReturningAdvice(JoinPoint joinPoint, MyLog mylog) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        logHandler(joinPoint, mylog, request, null);
    }

    // 异常通知
    @AfterThrowing(value = "@annotation(mylog)", throwing = "e")
    public void afterThrowingAdvice(JoinPoint joinPoint, MyLog mylog, Exception e) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        logHandler(joinPoint, mylog, request, e);
    }

    // 进行日志处理
    private void logHandler(JoinPoint joinPoint, MyLog mylog, HttpServletRequest request, Exception e) {
        OperLog operLog = new OperLog();
        // 注解中获取
        operLog.setTitle(mylog.title());
        // 注解中获取
        operLog.setBusinessType(mylog.businessType());
        // joinpoint中获取
        operLog.setMethod(joinPoint.getSignature().getName());
        // request中获取
        operLog.setReqMethod(request.getMethod());

        // request中获取
        User loginUser=(User)request.getSession().getAttribute("loginUser");
        if (loginUser!=null) {
            operLog.setOperName(loginUser.getName());
        }

        // request中获取
        operLog.setOperUrl(request.getRequestURI());
        // request中获取
        operLog.setOperIp(request.getRemoteAddr());
        // 判断是否有异常
        if (e!=null) {
            log.error("@打印错误日志");
            operLog.setStatus(LOG_ERROR);
            // 判断是否有异常
            operLog.setErrMsg(e.getMessage());
        } else operLog.setStatus(LOG_SUCCESS);
        operLog.setOperTime(new Date());

//        log.error("添加日志信息："+operLogService);
        // 添加日志信息
        operLogService.save(operLog);
    }

}
